package com.credithc.customers.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.credithc.customers.base.codes.CustomerCodes;
import com.credithc.customers.base.constants.CustomerConstants;
import com.credithc.customers.base.exception.CustomerException;
import com.credithc.customers.base.mapper.CustomerMapper;
import com.credithc.customers.base.mapper.CustomerStatsMapper;
import com.credithc.customers.base.mapper.PreCustomerMapper;
import com.credithc.customers.base.mapper.SystemInfoMapper;
import com.credithc.customers.base.po.CustomerInfoPo;
import com.credithc.customers.base.po.CustomerStatsPo;
import com.credithc.customers.base.po.PreCustomerInfoPo;
import com.credithc.customers.manager.echarts.CustomerCountStats;
import com.credithc.customers.manager.echarts.ExceptionPie;
import com.credithc.customers.manager.echarts.ModifyCountStats;
import com.credithc.customers.manager.mapper.EChartsMapper;
import com.credithc.customers.manager.po.CustomerModifyPo;
import com.credithc.customers.manager.po.ExceptionStatsPo;
import com.credithc.customers.manager.ro.HomeRo;
import com.credithc.customers.manager.service.ICustomerInfoService;
import com.credithc.customers.manager.service.IHomeService;
import com.credithc.customers.manager.utils.StatsUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zhukai
 * @date 2018/12/13 14:15
 */
@Service
public class HomeServiceImpl implements IHomeService {

    private final EChartsMapper eChartsMapper;

    private final SystemInfoMapper systemInfoMapper;

    private final ICustomerInfoService customerInfoService;

    private final CustomerStatsMapper statsMapper;

    private final PreCustomerMapper preMapper;

    private final CustomerMapper customerMapper;

    @Autowired
    public HomeServiceImpl(EChartsMapper eChartsMapper, SystemInfoMapper systemInfoMapper, ICustomerInfoService customerInfoService, CustomerStatsMapper statsMapper, PreCustomerMapper preMapper, CustomerMapper customerMapper) {
        this.eChartsMapper = eChartsMapper;
        this.systemInfoMapper = systemInfoMapper;
        this.customerInfoService = customerInfoService;
        this.statsMapper = statsMapper;
        this.preMapper = preMapper;
        this.customerMapper = customerMapper;
    }

    @Override
    public Map<String, String> statisticsHome(HomeRo ro) {
        if (ro == null) {
            ro = new HomeRo();
        }
        Map<String, String> map = new HashMap<>(4);
        if ("customerStatsLine".equals(ro.getRefreshType())) {
            map.put("customerStatsLine", generateCustomerLine(ro));
        } else if ("customerModifyBar".equals(ro.getRefreshType())) {
            map.put("customerModifyBar", generateModifyBar(ro));
        } else if ("customerStats".equals(ro.getRefreshType())) {
            map.put("customerStats", generateCustomerCount());
        } else if ("exceptionPie".equals(ro.getRefreshType())) {
            map.put("exceptionPie", generateExceptionPie());
        }
        return map;
    }

    private String generateCustomerCount() {

        List<CustomerStatsPo> list = getYesterdaySum();
        int todayPreCount = getTodayPreCount();
        int todayPersonalCount = getTodayPersonalCount();
        int todayPublicCount = getTodayPublicCount();
        Map<String, Map<String, Integer>> typeMap = new HashMap<>();
        for (CustomerStatsPo po : list) {
            Map<String, Integer> countMap = new HashMap<>();
            String type = po.getType();
            int count = po.getCount();
            if ("pre".equals(type)) {
                countMap.put("sum", count + todayPreCount);
                countMap.put("today", todayPreCount);
            } else if ("personal".equals(type)) {
                countMap.put("sum", count + todayPersonalCount);
                countMap.put("today", todayPersonalCount);
            } else if ("public".equals(type)) {
                countMap.put("sum", count + todayPublicCount);
                countMap.put("today", todayPublicCount);
            }
            typeMap.put(type, countMap);
        }

        Map<String, Object> map = customerInfoService.selectPreStatic();
        int total = (Integer) map.get("total");
        int changed = (Integer) map.get("changed");
        Map<String, Integer> systemMap = new HashMap<>();
        systemMap.put("today", changed);
        systemMap.put("sum", total);
        typeMap.put("system", systemMap);
        return JSON.toJSONString(typeMap);
    }

    private String generateCustomerLine(HomeRo ro) {
        List<String> xAxisList = new ArrayList<>();
        if (StringUtils.isBlank(ro.getCustomerStateType())) {
            //点击查询按钮触发
            if (StringUtils.isBlank(ro.getCustomerStateDateStart()) || StringUtils.isBlank(ro.getCustomerStateDateEnd())) {
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "请选择统计时间");
            } else {
                xAxisList = StatsUtils.generateXAxisList(ro.getCustomerStateDateStart(), ro.getCustomerStateDateEnd(), "customized");
            }
        } else {
            //切换tab触发。week-month
            xAxisList = StatsUtils.generateXAxisList(ro.getCustomerStateDateStart(), ro.getCustomerStateDateEnd(), ro.getCustomerStateType());
        }
        String startDate = xAxisList.get(0);
        String endDate = xAxisList.get(xAxisList.size()-1);

        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        List<CustomerStatsPo> list = getYesterdayCount(startDate, endDate);
        if(endDate.equals(date)){
            int todayPreCount = getTodayPreCount();
            CustomerStatsPo prePo = new CustomerStatsPo();
            prePo.setDate(endDate);
            prePo.setCount(todayPreCount);
            prePo.setType("pre");
            list.add(prePo);

            int todayPersonalCount = getTodayPersonalCount();
            CustomerStatsPo personalPo = new CustomerStatsPo();
            personalPo.setDate(endDate);
            personalPo.setCount(todayPersonalCount);
            personalPo.setType("personal");
            list.add(personalPo);

            int todayPublicCount = getTodayPublicCount();
            CustomerStatsPo publicPo = new CustomerStatsPo();
            publicPo.setDate(endDate);
            publicPo.setCount(todayPublicCount);
            publicPo.setType("public");
            list.add(publicPo);
        }
        CustomerCountStats customerStats = new CustomerCountStats(list, xAxisList);
        return customerStats.generateGraph();
    }


    private List<CustomerStatsPo> getYesterdayCount(String startDate,String endDate) {
        Example example = new Example(CustomerStatsPo.class);
        example.setDistinct(false);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("statsType",CustomerConstants.STATS_CUSTOMER_COUNT);
        criteria.andGreaterThanOrEqualTo("date",startDate);
        criteria.andLessThanOrEqualTo("date",endDate);
        List<CustomerStatsPo> list = statsMapper.selectByExample(example);
        return list;
    }

    private List<CustomerStatsPo> getYesterdaySum() {
        CustomerStatsPo statsPo = new CustomerStatsPo();
        statsPo.setStatsType(CustomerConstants.STATS_CUSTOMER_SUM);
        List<CustomerStatsPo> list = statsMapper.select(statsPo);
        return list;
    }

    private int getTodayPreCount() {
        PreCustomerInfoPo po = new PreCustomerInfoPo();
        po.setCreateDate(new java.sql.Date(System.currentTimeMillis()));
        return preMapper.selectCount(po);
    }

    private int getTodayPersonalCount() {
        CustomerInfoPo po = new CustomerInfoPo();
        po.setCreateDate(new java.sql.Date(System.currentTimeMillis()));
        po.setCustomerType(CustomerConstants.CUSTOMER_TYPE_PERSON);
        return customerMapper.selectCount(po);
    }

    private int getTodayPublicCount() {
        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        Example example = new Example(CustomerInfoPo.class);
        example.setDistinct(false);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("createDate", date);
        criteria.andNotEqualTo("customerType", CustomerConstants.CUSTOMER_TYPE_PERSON);
        return customerMapper.selectCountByExample(example);

    }


    private String generateModifyBar(HomeRo ro) {
        List<String> xAxisLis = new ArrayList<>();
        String date = ro.getModifyStateDate();
        if (StringUtils.isBlank(date)) {
            date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        }
        xAxisLis.add(date);
        List<CustomerModifyPo> pos = eChartsMapper.statsCustomerModifyCount(date);
        ModifyCountStats modifyCountStats = new ModifyCountStats(pos, xAxisLis);
        return modifyCountStats.generateGraph();
    }

    private String generateExceptionPie() {
        List<ExceptionStatsPo> pos = eChartsMapper.statsExceptionCount();
        List<String> colList = new ArrayList<>();
        for (ExceptionStatsPo po : pos) {
            colList.add(po.getType());
        }
        ExceptionPie exceptionPie = new ExceptionPie(pos, colList);
        return exceptionPie.generateGraph();
    }

    public String division(int num1, int num2) {
        String rate = "0.00%";
        //定义格式化起始位数
        String format = "0.00";
        if (num2 != 0 && num1 != 0) {
            DecimalFormat dec = new DecimalFormat(format);
            rate = dec.format((double) num1 / num2 * 100) + "%";
            while (true) {
                if (rate.equals(format + "%")) {
                    format = format + "0";
                    DecimalFormat dec1 = new DecimalFormat(format);
                    rate = dec1.format((double) num1 / num2 * 100) + "%";
                } else {
                    break;
                }
            }
        } else if (num1 != 0 && num2 == 0) {
            rate = "100%";
        }
        return rate;
    }


}


